/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.ramotion.expandingcollection;

import java.util.ArrayList;
import java.util.List;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DependentLayout;
import ohos.agp.components.ListContainer;
import ohos.agp.components.StackLayout;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.agp.utils.LayoutAlignment;

/**
 * MainAbility
 *
 * @since 2021-05-31
 */
public class MainAbility extends Ability {
    private static final int DURATION = 200;
    private static final int CONSTANT_2 = 2;
    private static final int CONSTANT_1000 = 1000;
    private EcPager pageSlider;
    private boolean isCollapse;
    private int fullWidth;
    private int fullHeight;
    private CardListItemProvider provider;
    private int width;
    private int height;
    private AnimatorValue animator;
    private final List<ListContainer> listContainers = new ArrayList<>();
    private AnimatorValue animatorOther;

    /**
     * onStart
     *
     * @param intent
     */
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initViews();
    }

    private void initViews() {
        EcBackgroundSwitcherView ecSwitcher = (EcBackgroundSwitcherView) findComponentById(ResourceTable.Id_ecSwitcher);
        DependentLayout rootView = (DependentLayout) findComponentById(ResourceTable.Id_rootView);
        rootView.setClipEnabled(false);
        pageSlider = (EcPager) findComponentById(ResourceTable.Id_pageSlider);
        width = pageSlider.getCardWidth();
        height = pageSlider.getCardHeight();
        fullWidth = ResUtils.getScreenWidth(getContext());
        fullHeight = ResUtils.getScreenHeight(getContext());
        List<EcCardData> dataList = CardDataImpl.generateExampleData();
        dataList.remove(CONSTANT_2);
        EcPagerViewAdapter ecProvider = new EcPagerViewAdapter(dataList) {
            @Override
            public void instantiateCard(ComponentContainer componentContainer, int position, EcCardData data) {
                CardDataImpl cardData = (CardDataImpl) data;
                setViews(componentContainer, position, cardData);
            }
        };
        pageSlider.setPagerViewAdapter(ecProvider, dataList);
        pageSlider.setBackgroundSwitcherView(ecSwitcher);
        pageSlider.addPageChangedListener(new PageChangedListener() {
            @Override
            public void onPageSliding(int position, float positionOffset, int positionOffsetPixels) {
                AlphaScalePageTransformer.transformPage(listContainers, position, positionOffset, positionOffsetPixels);
            }
        });
    }

    private void setViews(ComponentContainer componentContainer, int position, CardDataImpl cardData) {
        ListContainer listContainer = new ListContainer(MainAbility.this);
        provider = new CardListItemProvider(MainAbility.this, cardData, cardData.getListItems());
        listContainer.setItemProvider(provider);
        listContainer.setEnabled(false);
        listContainers.add(listContainer);
        listContainer.setLongClickable(false);
        StackLayout.LayoutConfig layoutParams = new StackLayout.LayoutConfig(width, height);
        layoutParams.alignment = LayoutAlignment.CENTER;
        ShapeElement element = new ShapeElement();
        element.setRgbColor(RgbColor.fromArgbInt(Color.getIntColor("#FFFFFF")));
        componentContainer.addComponent(listContainer, layoutParams);
        listContainer.setBackground(element);
        AlphaScalePageTransformer.defaultPage(listContainer, position, pageSlider.getCurrentPage());
        if (position != pageSlider.getCurrentPage()) {
            provider.setAlpha(AlphaScalePageTransformer.INACTIVE_ALPHA);
        }
        listContainer.setItemClickedListener((listContainer1, component, pos, l) -> {
            if (pos == 0 && pageSlider.isSwitch()) {
                toggle();
            }
        });
    }

    private void toggle() {
        ListContainer listContainer = listContainers.get(pageSlider.getCurrentPage());
        if (isCollapse) {
            isCollapse = false;
            pageSlider.setSlidingPossible(true);
            listContainer.setEnabled(false);
            listContainer.scrollTo(0, 0);
            startAnimate(listContainer, CONSTANT_1000, 0);
        } else {
            isCollapse = true;
            pageSlider.setSlidingPossible(false);
            listContainer.setEnabled(true);
            startAnimate(listContainer, 0, CONSTANT_1000);
        }
        ((CardListItemProvider) listContainer.getItemProvider()).setAlpha(1);
    }

    private void startAnimate(ListContainer listContainer, float start, float end) {
        if (animatorOther != null) {
            animatorOther.stop();
        }
        if (animator != null) {
            animator.stop();
        }
        AnimatorValueUtil animatorValueUtil = new AnimatorValueUtil();
        float[] fromTo = {start, end};
        animatorValueUtil.ofFloat(fromTo);
        animator = new AnimatorValue();
        animator.setDuration(DURATION);
        int deltaWidth = fullWidth - width;
        int deltaHeight = fullHeight - height;
        animator.setValueUpdateListener((animatorValue1, val) -> {
            float current = animatorValueUtil.getValue(val);
            listContainer.setWidth(width + (int) current * deltaWidth / CONSTANT_1000);
            listContainer.setHeight(height + (int) current * deltaHeight / CONSTANT_1000);
        });
        animator.setStateChangedListener(new AnimatorListener() {
            @Override
            public void onStart(Animator animato) {
                if (isCollapse) {
                    startOtherAnimate(EcPager.PAGE_MARGIN, 0);
                }
            }

            @Override
            public void onStop(Animator animato) {
                if (!isCollapse) {
                    startOtherAnimate(0, EcPager.PAGE_MARGIN);
                }
            }
        });
        animator.start();
    }

    private void startOtherAnimate(float start, float end) {
        AnimatorValueUtil animatorValueUtil1 = new AnimatorValueUtil();
        float[] fromTo = {start, end};
        animatorValueUtil1.ofFloat(fromTo);
        animatorOther = new AnimatorValue();
        animatorOther.setDuration(DURATION);
        animatorOther.setValueUpdateListener((animatorValue1, v) -> {
            float current = animatorValueUtil1.getValue(v);
            pageSlider.setPageMargin((int) current);
        });
        animatorOther.start();
    }

    /**
     * onBackPressed
     */
    @Override
    protected void onBackPressed() {
        if (!isCollapse) {
            super.onBackPressed();
        } else {
            toggle();
        }
    }
}
